package com.yk.neon.lib.util.base.date;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.Calendar;
import java.util.Date;
import java.util.regex.Pattern;

/**
 * @author yangke
 * @date 2023/6/28
 * @time 15:01
 * @Description 日期工具类
 */
public class DateUtil {

    private static  String DATEREGEX1 = "\\d{4}-\\d{2}-\\d{2}";
    private static String DATEREGEX2 = "\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}";
    private static String PATTERN1 = "yyyy-MM-dd";
    private static String PATTERN2 = "yyyy-MM-dd HH:mm:ss";
    /**
     * 日期类型转化为String类型
     * @param date
     * @param pattern
     * @return
     */
    public static String dateToString(Date date,String pattern){
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
        return sdf.format(date);
    }

    /**
     * String类型转化为Date类型
     * @param dateStr
     * @param pattern
     * @return
     * @throws ParseException
     */
    public static Date stringToDate(String dateStr, String pattern) throws ParseException {
        SimpleDateFormat formatter = new SimpleDateFormat(pattern);
        return formatter.parse(dateStr);
    }


    /**
     * LocalDate类型转换为Date类型
     * @param localDate
     * @return
     */
    public static Date localDateToDate(LocalDate localDate) {
        return Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant());
    }

    /**
     * Date类型转换为LocalDate类型
     * @param date
     * @return
     */
    public static LocalDate dateToLocalDate(Date date) {
        return date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
    }

    /**
     * Date类型转换为LocalDateTime类型
     * @param date
     * @return
     */
    public static LocalDateTime dateToLocalDateTime(Date date){
        return date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
    }

    /**
     * LocalDateTime类型转换为Date类型
     * @param localDateTime
     * @return
     */
    public static Date localDateTimeToDate(LocalDateTime localDateTime){
        LocalDate localDate = localDateTime.toLocalDate();
        return Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant());
    }

    /**
     * 得到两个日期相差几天（精确到天）
     * @param date1 ：yyyy-MM-dd格式
     * @param date2 ：yyyy-MM-dd格式
     * @return
     */
    public static Long getBetweenDayFromDay(String date1, String date2){
        LocalDate localDate1 = LocalDate.parse(date1);
        LocalDate localDate2 = LocalDate.parse(date2);
        return ChronoUnit.DAYS.between(localDate1, localDate2);
    }

    /**
     * 得到两个日期相差几天（精确到分钟）
     * @param date1 ：yyyy-MM-dd HH:mm:ss格式
     * @param date2 ：yyyy-MM-dd HH:mm:ss格式
     * @return
     */
    public static Long getBetweenDayFromMinute(String date1, String date2){
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LocalDateTime dateTime1 = LocalDateTime.parse(date1, formatter);
        LocalDateTime dateTime2 = LocalDateTime.parse(date2, formatter);
        return Duration.between(dateTime1, dateTime2).toMinutes() / (24 * 60);
    }

    /**
     * 获取指定日期的年份
     * @param date
     * @return
     */
    public static int getYear(Date date){
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.YEAR);
    }

    /**
     * 获取指定日期的月份
     * @param date
     * @return
     */
    public static int getMonth(Date date){
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.MONTH) + 1;
    }

    /**
     * 获取指定日期的天
     * @param date
     * @return
     */
    public static int getDay(Date date){
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.DAY_OF_MONTH);
    }

    /**
     * 获取指定日期的小时
     * @param date
     * @return
     */
    public static int getHour(Date date){
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.HOUR_OF_DAY);
    }

    /**
     * 获取指定日期的分钟
     * @param date
     * @return
     */
    public static int getMinute(Date date){
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.MINUTE);
    }

    /**
     * 获取指定日期的秒
     * @param date
     * @return
     */
    public static int getSecond(Date date){
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.SECOND);
    }

    /**
     * 得到当前日期的天数
     * @param date
     * @return
     */
    public static int getLastDayOfMonth(Date date){
        // 创建Calendar对象并设置为当前日期
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        // 获取当前月份的最后一天
        return calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
    }

    /**
     * 判断传入的日期是否是闰年
     * @param date
     * @return
     */
    public static boolean isLeapYear(Date date){
        // 创建Calendar对象并设置为指定日期
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        // 获取指定日期所在年份
        int year = calendar.get(Calendar.YEAR);
        // 判断是否是闰年
        boolean isLeapYear = false;
        if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) {
            isLeapYear = true;
        }
        return isLeapYear;
    }

    /**
     * 比较两个字符串时间大小，带时分秒的，date2大于date1返回true
     * @param date1
     * @param date2
     * @return
     */
    public static Boolean compareDateStr(String date1, String date2) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date d1 = sdf.parse(date1);
        Date d2 = sdf.parse(date2);
        if (d2.getTime() - d1.getTime() > 0) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 比较两个字符串时间大小，带时分秒的，date2大于date1返回true
     * @param date1
     * @param date2
     * @return
     */
    public static Boolean compareDate(String date1, String date2) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat();
        if(isDateFormat(date1) && isDateFormat(date2)){
            sdf = new SimpleDateFormat(PATTERN1);
        }
        if(isDateTimeFormat(date1) && isDateTimeFormat(date2)){
            sdf = new SimpleDateFormat(PATTERN2);
        }
        Date d1 = sdf.parse(date1);
        Date d2 = sdf.parse(date2);
        return d2.getTime() - d1.getTime() > 0L;
    }

    /**
     * 判断日期字符串是否为yyyy-MM-dd格式
     */
    public static boolean isDateFormat(String dateStr) {
        return Pattern.matches(DATEREGEX1, dateStr);
    }

    /**
     * 判断日期字符串是否为yyyy-MM-dd HH:mm:ss格式
     */
    public static boolean isDateTimeFormat(String dateStr) {
        return Pattern.matches(DATEREGEX2, dateStr);
    }
}
